﻿//
// <author>David Nohejl</author>
//
// This file contains implementation of commands.
//
using WPFTrees.Parser;
using WPFTrees.DataStructures;
using System.Windows;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Data;
using Microsoft.Win32;
using System.Windows.Documents;
using System.Diagnostics;
using System.Reflection;
using System.IO;
namespace WPFTrees
{
    public partial class MainWindow
    {
        /// <summary>
        /// Vyhledavani mezi listy stromu, na podobne retezce. Case senzitive.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void FindOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            labels.ForEach(delegate(Label label)
            {
                if (label.Content.ToString().Contains(txtBoxFind.Text))
                {
                    label.Background = DefaultSettings.Default.HiglightedNodeColor;
                }
                else 
                {
                    label.Background = Brushes.Transparent;                    
                }
            });
        }

        /// <summary>
        /// Zobrazi dialog tisku, a vytiskne workspace.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void PrintPreviewOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            PrintDialog dlg = new PrintDialog();

            if (dlg.ShowDialog() == true)
            {
                // parentCanvas je canvas ve kterem je cely workspace
                dlg.PrintVisual(parentCanvas, "Test");                
            }
        }

        void ZoomOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            switch (args.Parameter.ToString())
            {
                case "in":
                    scaleRatio += 0.1;
                    break;
                case "out":
                    scaleRatio -= 0.1;
                    break;
            }
          
            RenderTree(CurrentTree);
        }

        //
        // Otevirani souboru se stromy.
        //
        void OpenOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            OpenFileDialog dlgOpen = new OpenFileDialog();
            dlgOpen.Filter = "Text files|*.txt|All Files|*.*";
            dlgOpen.DefaultExt = "*.txt";
            long parsedInMs, renderedInMs;

            if (dlgOpen.ShowDialog() == true)
            {
                try
                {
                    Stopwatch watch = new Stopwatch();
                    watch.Start();
                    using (Stream stream = dlgOpen.OpenFile())
                    {
                        NTree<NewickNode> newTree = NewickParser.Parse(stream);
                        parsedInMs = watch.ElapsedMilliseconds;
                        watch.Reset();
                        CurrentTree = newTree;
                        CurrentTree.Info.Path = dlgOpen.FileName;
                        renderedInMs = watch.ElapsedMilliseconds;
                    }
                }
                catch (ParserException ex)
                {
                    // neplatny vstupni soubor
                    MessageBox.Show( string.Format("There was problem reading "
                                            +"input tree: {0}", ex.Message),
                                    "Input error.",
                                    MessageBoxButton.OK,
                                    MessageBoxImage.Error);

                    statusBar1.Items[0] = string.Format("There was error "
                                            +"reading {0}.", dlgOpen.FileName);
                    return;
                }
                // nastav ve status baru informace
                TreeInfo<NewickNode> info = CurrentTree.Info;
                statusBar1.Items[0] = string.Format("Tree {0} loaded. Parsed in"
                                            +"{4}, rendered in {5}. Nodes: {1}."
                                            +"Leaves: {2}. Is binary: {3}",
                                            dlgOpen.FileName,
                                            CurrentTree.GetRoot().CountChildren,
                                            info.Leaves.Count,
                                            info.IsBinary,
                                            parsedInMs,
                                            renderedInMs);
            }

        }

        void CloseOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            Close();
        }

        #region Rotace stromu
        
        /// <summary>
        /// Otoci kanvas o 90 stupnu doleva.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void RotateLeftOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            RotateTransform rotateLeft = new RotateTransform(-90,0.5,0.5);
            MatrixTransform transform = new MatrixTransform(
                canvas.LayoutTransform.Value * rotateLeft.Value);
            canvas.LayoutTransform = transform;
            
            if (!bRotateLabels)
            {
                foreach (Label label in labels)
                {
                    Matrix inverse = rotateLeft.Value;
                    inverse.Invert();            
                    label.LayoutTransform = new MatrixTransform(
                        label.LayoutTransform.Value * inverse);
                }
            }          
        }

        /// <summary>
        /// Otoci kanvas o 90 stupnu doprava.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void RotateRightOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            RotateTransform rotateRight = new RotateTransform(90,0.5,0.5);
            MatrixTransform transform = new MatrixTransform(
                canvas.LayoutTransform.Value* rotateRight.Value);
            canvas.LayoutTransform = transform;

            if (!bRotateLabels)
            {
                foreach (Label label in labels)
                {
                    Matrix inverse = rotateRight.Value;
                    inverse.Invert();                    
                    label.LayoutTransform = new MatrixTransform(
                            label.LayoutTransform.Value * inverse);
                }                
            }            
        }

        #endregion     

        void ShowTreePropertiesOnExecute(object sender,
            ExecutedRoutedEventArgs args)
        {
            PropertyDialogs.TreePropertyDlg dlg = 
                new PropertyDialogs.TreePropertyDlg(tree);
            dlg.ShowDialog();
        }

        void HelpRequestedOnExecute(object sender, ExecutedRoutedEventArgs args)
        {
            string appPath = System.IO.Path.GetDirectoryName(
                Assembly.GetExecutingAssembly().Location);
            Process.Start(appPath + @"\wpftrees.chm");
        }
    }
}
